package org.elsfs.cloud.common.mybatis.ext.mybatis.extension;


import lombok.AccessLevel;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.elsfs.cloud.common.core.entity.BaseEntity;

import java.util.Arrays;
import java.util.List;

/**
 * 实体关系描述
 *

 */
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class EntityRelationDescriptor {

    /**
     * 实体类
     */
    private final Class<? extends BaseEntity> entityClass;
    /**
     * 外键字段名称
     */
    private final String foreignKeyField;
    /**
     * 连接字段名称
     */
    private final String joinKeyField;
    /**
     * 关联选择字段
     */
    private final List<String> selectionFields;

    /**
     * 创建实体关联描述对象
     *
     * @param entityClass 实体类
     * @param foreignKeyField 外键字段
     * @param selectionFields 选择字段
     * @return 实体关系描述对象
     */
    public static EntityRelationDescriptor create(Class<? extends BaseEntity> entityClass, String foreignKeyField, String... selectionFields) {
        return new EntityRelationDescriptor(
            entityClass,
            foreignKeyField,
            null,
            Arrays.asList(selectionFields)
        );
    }

    /**
     * 创建实体关联描述对象
     *
     * @param entityClass 实体类
     * @param foreignKeyField 外键字段
     * @param selectionFields 选择字段
     * @return 实体关系描述对象
     */
    public static EntityRelationDescriptor create(Class<? extends BaseEntity> entityClass, Enum<?> foreignKeyField, String... selectionFields) {
        return new EntityRelationDescriptor(
            entityClass,
            foreignKeyField.name(),
            null,
            Arrays.asList(selectionFields)
        );
    }

    /**
     * 创建一个实体关联描述符构建器
     *
     * @param entityClass 实体类
     * @param foreignKeyField 主表中外键字段名称
     * @return 构建器
     */
    public static EntityRelationDescriptorBuilder builder(Class<? extends BaseEntity> entityClass, String foreignKeyField) {
        return new EntityRelationDescriptorBuilder(entityClass, foreignKeyField);
    }

    /**
     * 创建一个实体关联描述符构建器
     *
     * @param entityClass 实体类
     * @param foreignKeyField 主表中外键字段名称枚举
     * @return 构建器
     */
    public static EntityRelationDescriptorBuilder builder(Class<? extends BaseEntity> entityClass, Enum<?> foreignKeyField) {
        return new EntityRelationDescriptorBuilder(entityClass, foreignKeyField.name());
    }

    /**
     * 实体关联描述符构建器
     */
    @RequiredArgsConstructor
    public static class EntityRelationDescriptorBuilder {
        /**
         * 关联实体类
         */
        private final Class<? extends BaseEntity> entityClass;
        /**
         * 外键字段名称
         */
        private final String foreignKeyField;
        /**
         * 关联选择字段
         */
        private final List<String> selectionFields = Lists.newArrayList();
        /**
         * 连接字段名称
         */
        private String joinKeyField;

        /**
         * 设置连接字段
         *
         * @param field 字段名称
         * @return 构建器
         */
        public EntityRelationDescriptorBuilder joinKeyField(String field) {
            this.joinKeyField = field;
            return this;
        }

        /**
         * 设置连接字段
         *
         * @param field 字段名称枚举
         * @return 构建器
         */
        public EntityRelationDescriptorBuilder joinKeyField(Enum<?> field) {
            this.joinKeyField = field.name();
            return this;
        }

        /**
         * 选择字段
         *
         * @param field 字段名称
         * @return 构建器
         */
        public EntityRelationDescriptorBuilder select(String field) {
            this.selectionFields.add(field);
            return this;
        }

        /**
         * 选择字段
         *
         * @param field 字段名称枚举
         * @return 构建器
         */
        public EntityRelationDescriptorBuilder select(Enum<?> field) {
            this.selectionFields.add(field.name());
            return this;
        }

        /**
         * 选择字段
         *
         * @param field 字段名称
         * @param alias 字段别名
         * @return 构建器
         */
        public EntityRelationDescriptorBuilder selectAs(String field, String alias) {
            this.selectionFields.add(
                field + " AS " + alias
            );
            return this;
        }

        /**
         * 选择字段
         *
         * @param field 字段名称枚举
         * @param alias 字段别名枚举
         * @return 构建器
         */
        public EntityRelationDescriptorBuilder selectAs(Enum<?> field, Enum<?> alias) {
            this.selectionFields.add(
                field.name() +" AS " + alias.name()
            );
            return this;
        }

        /**
         * 选择字段
         *
         * @param field 字段名称枚举
         * @param alias 字段别名
         * @return 构建器
         */
        public EntityRelationDescriptorBuilder selectAs(Enum<?> field, String alias) {
            this.selectionFields.add(
                field.name() + " AS " + alias
            );
            return this;
        }

        /**
         * 选择字段
         *
         * @param field 字段名称
         * @param alias 字段别名枚举
         * @return 构建器
         */
        public EntityRelationDescriptorBuilder selectAs(String field, Enum<?> alias) {
            this.selectionFields.add(
                field +" AS " + alias.name()
            );
            return this;
        }

        /**
         * 构建实体关联描述符
         *
         * @return 实体关联描述符
         */
        public EntityRelationDescriptor build() {
            return new EntityRelationDescriptor(
                this.entityClass,
                this.foreignKeyField,
                this.joinKeyField,
                this.selectionFields
            );
        }
    }
}
